package com.gjy.spring.s6;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;

/**
 * Aware InitializingBean
 * @author 宫静雨
 * @version 1.0
 * @since 2023-12-20 09:36:52
 */
public class S6App {
    private static final Logger log = LoggerFactory.getLogger(S6App.class);

    public static void main(String[] args) {
        /*
        1. Aware 接口用于注入一些与容器相关信息
          a. BeanNameAware 注入 bean 的名字
          b. BeanFactoryAware 注入 BeanFactory 容器
          c. ApplicationContextAware 注入 ApplicationContext 容器
          d. EmbeddedValueResolverAware 注入 PropertySourcesPlaceholderConfigurer 解析器 ${}
         */
        GenericApplicationContext context = new GenericApplicationContext();
        //context.registerBean("myBean",MyBean.class);
        //context.registerBean("myConfig1", MyConfig1.class);
        context.registerBean("myConfig2", MyConfig2.class);
        context.registerBean(AutowiredAnnotationBeanPostProcessor.class);
        context.registerBean(CommonAnnotationBeanPostProcessor.class);
        context.registerBean(ConfigurationClassPostProcessor.class);

        /* 对应MyBean
        b,c,d都能用@Autowired实现，为什么要用Aware呢？
            @Autowired的解析需要用到bean后处理器，属于扩展功能。
            Aware属于内置功能，不需要扩展，Spring就能识别。
        某些情况下扩展功能会失效，而内置功能不会失效。
        例一：Aware注入ApplicationContext成功，@Autowired注入失败
         */
        /* 对应 MyConfig1 MyConfig2
        例二：Java配置类再添加了Bean工厂后处理器后，Aware的注入和初始化仍然成功，而@Autowired和@PostConstruct失败
         */
        context.refresh(); // 1.beanFactory后处理器， 2.添加bean后处理器，3.初始化所有的单例
        context.close();
        /*
        1. Aware 接口提供了一种【内置】的注入手段，可以注入BeanFactory，ApplicationContext
        2. InitializingBean 接口提供了一种【内置】的初始化手段
        3. 内置的注入和初始化不受扩展功能的影响，总会被执行，因此Spring框架内部的类常用它们。
         */
    }
}
